﻿using StackExchange.Redis;
using System;
using System.Threading.Tasks;

namespace D.Medicalcare.Read.API.Helper;

public class RedisDistributedLock
{
    private readonly IDatabase _redisDatabase;
    private readonly string _lockKey;
    private readonly string _lockValue;
    private readonly TimeSpan _expiry;

    public RedisDistributedLock(IDatabase redisDatabase, string lockKey)
    {
        _redisDatabase = redisDatabase;
        _lockKey = lockKey;
        _lockValue = Guid.NewGuid().ToString();// 锁的值，确保唯一性
        _expiry = TimeSpan.FromMinutes(5); // 锁的过期时间;
    }
    /// <summary>
    /// 加锁
    /// </summary>
    /// <returns></returns>
    public async Task<bool> AcquireLockAsync()
    {
        // 尝试设置锁，仅当键不存在时才成功
        return await _redisDatabase.StringSetAsync(_lockKey, _lockValue, _expiry, When.NotExists);
    }

    /// <summary>
    /// 释放锁
    /// </summary>
    /// <returns></returns>
    public async Task ReleaseLockAsync()
    {
        // 使用 Lua 脚本确保只有锁的持有者才能释放锁
        var luaScript = @"
            if redis.call('GET', KEYS[1]) == ARGV[1] then
                return redis.call('DEL', KEYS[1])
            else
                return 0
            end";

        await _redisDatabase.ScriptEvaluateAsync(luaScript, new RedisKey[] { _lockKey }, new RedisValue[] { _lockValue });
    }
}